﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Net;

namespace MnxTerminal.Controls
{
    public delegate void IPv4AddressChangedEventHandler(object sender, EventArgs e);

    public partial class IPv4TextBox : UserControl
    {
        private String _tmp;

        /// <summary>
        /// Gets or sets the contained and visible IP address of the control (default = 0.0.0.0).
        /// </summary>
        [Browsable(false)]
        public IPAddress Address
        {
            get
            {
                try
                {
                    return IPAddress.Parse(tB_Octet0.Text + "."
                                            + tB_Octet1.Text + "."
                                            + tB_Octet2.Text + "."
                                            + tB_Octet3.Text);
                }
                catch
                {
                    throw;
                }
            }
            set
            {
                SetIPAddress(value);
            }
        }

        public event IPv4AddressChangedEventHandler AddressChanged;

        public IPv4TextBox()
        {
            InitializeComponent();

            _tmp = String.Empty;
        }

        private delegate void SetIPAddressDelegate(IPAddress value);
        private void SetIPAddress(IPAddress value)
        {
            if (InvokeRequired)
            {
                SetIPAddressDelegate d = new SetIPAddressDelegate(SetIPAddress);
                Invoke(d, new object[] { value });
            }
            else
            {
                SuspendLayout();

                String[] token = new String[4];
                token = value.ToString().Split(new char[] { '.' }, 4);

                tB_Octet0.Text = token[0];
                tB_Octet1.Text = token[1];
                tB_Octet2.Text = token[2];
                tB_Octet3.Text = token[3];

                ResumeLayout();
                Update();
            }
        }

        private void tB_Octet_Enter(object sender, EventArgs e)
        {
            TextBox tB = (TextBox)sender;

            _tmp = tB.Text;

            tB.SelectionStart = 0;
            tB.SelectionLength = tB.Text.Length;
        }

        private void tB_Octet_Leave(object sender, EventArgs e)
        {
            TextBox tB = (TextBox)sender;

            if (String.IsNullOrEmpty(tB.Text))
            {
                tB.Text = "0";
            }
        }

        private void tB_Octet_TextChanged(object sender, EventArgs e)
        {
            TextBox tB = (TextBox)sender;

            if (String.IsNullOrEmpty(tB.Text))
            {
                _tmp = tB.Text;
                return;
            }

            Boolean valid = true;
            for (Int32 i = 0; i < tB.Text.Length; i++)
            {
                valid &= Char.IsDigit(tB.Text[i]);
            }

            Byte result;
            if (!Byte.TryParse(tB.Text, out result) || !valid)
            {
                tB.Text = _tmp;
                tB.SelectionStart = tB.Text.Length;

                return;
            }

            _tmp = tB.Text;

            if (tB.SelectionStart == 3 && tB.Name != "tB_Octet3")
            {
                SelectNextControl(tB, true, true, false, false);
            }

            if (AddressChanged != null)
            {
                AddressChanged(this, null);
            }
        }

        private void tB_Octet_KeyDown(object sender, KeyEventArgs e)
        {
            TextBox tB = (TextBox)sender;

            if (e.KeyCode == Keys.Left && tB.SelectionStart == 0 && tB.Name != "tB_Octet0")
            {
                SelectNextControl(tB, false, true, false, false);
                e.Handled = true;

                return;
            }

            if (e.KeyCode == Keys.Right && tB.SelectionStart == tB.Text.Length && tB.Name != "tB_Octet3")
            {
                SelectNextControl(tB, true, true, false, false);
                e.Handled = true;

                return;
            }
        }

        private void IPv4TextBox_EnabledChanged(object sender, EventArgs e)
        {
            SuspendLayout();

            if (Enabled)
            {
                BackColor = SystemColors.Window;
            }
            else
            {
                BackColor = SystemColors.Control;
            }

            ResumeLayout();
        }
    }
}
